/**
 * Distributable under LGPL license.
 * See terms of license at gnu.org.
 */
package sudokupso;

/**
 *
 * @author Alex
 */
public class Main {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
        System.out.println("Start!");
        int[][] solved = new int[][]{
            {7, 8, 2, 1, 4, 9, 5, 3, 6},
            {3, 4, 1, 6, 5, 7, 9, 8, 2},
            {9, 5, 6, 2, 3, 8, 4, 1, 7},
            {5, 9, 7, 3, 1, 2, 8, 6, 4},
            {8, 2, 3, 4, 9, 6, 7, 5, 1},
            {1, 6, 4, 8, 7, 5, 2, 9, 3},
            {4, 7, 9, 5, 6, 1, 3, 2, 8},
            {6, 3, 8, 9, 2, 4, 1, 7, 5},
            {2, 1, 5, 7, 8, 3, 6, 4, 9},};
        Particle part = new Particle(solved);
        System.out.println(part);
        System.out.println(part.getFitness());
        System.out.println("");

//        int[][] test = new int[][]{
//            {-1, 8, -1, -1, 4, -1, -1, 3, -1, -1, -1, -1, -1, -1, -1, -1},
//            {3, -1, -1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
//            {-1, 5, 6, 2, -1, -1, -1, -1, 7, -1, -1, -1, -1, -1, -1, -1},
//            {-1, 9, 7, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
//            {8, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1},
//            {-1, -1, -1, -1, -1, 5, 2, 9, -1, -1, -1, -1, -1, -1, -1, -1},
//            {4, -1, -1, -1, -1, 1, 3, 2, -1, -1, -1, -1, -1, -1, -1, -1},
//            {-1, -1, -1, -1, -1, 4, -1, -1, 5, -1, -1, -1, -1, -1, -1, -1},
//            {-1, 1, -1, -1, 8, -1, -1, 4, -1, -1, -1, -1, -1, -1, -1, -1},
//            {-1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
//            {-1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
//            {-1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
//            {-1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
//            {-1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
//            {-1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
//            {-1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},};
        int[][] test = new int[][]{
            {-1, 8, -1, -1, 4, -1, -1, 3, -1},
            {3, -1, -1, 6, -1, -1, -1, -1, -1},
            {-1, 5, 6, 2, -1, -1, -1, -1, 7},
            {-1, 9, 7, 3, -1, -1, -1, -1, -1},
            {8, -1, -1, -1, -1, -1, -1, -1, 1},
            {-1, -1, -1, -1, -1, 5, 2, 9, -1},
            {4, -1, -1, -1, -1, 1, 3, 2, -1},
            {-1, -1, -1, -1, -1, 4, -1, -1, 5},
            {-1, 1, -1, -1, 8, -1, -1, 4, -1},};
        Particle part1 = new Particle(test);
        System.out.println(part1);
        System.out.println(part1.getFitness());

        System.out.println("Starting PSO algorithm");

        long fitnessSums = 0;
        for (int i = 0; i < Constants.MAX_RUNS; i++) {
            GeometricPSO algorithm = new GeometricPSO(test);
            Thread algorithmThread = new Thread(algorithm);
            algorithmThread.start();
            try {
                algorithmThread.join();
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }

            //System.out.println("Global best:");
            //System.out.println(algorithm.getGlobalBest());
            long fitness = algorithm.getGlobalBest().getFitness();
            fitnessSums += fitness;
            System.out.println("Global best fitness: " + fitness);
        }
        System.out.println("Average fitness over " + Constants.MAX_RUNS + " runs = " + ((double)fitnessSums / (double)Constants.MAX_RUNS));

    /*part1.mutate();
    System.out.println(part1);
    System.out.println(part1.getFitness());
    part1.crossover(part1);
    System.out.println(part1.getFitness());*/
    }
}
